1 =============================================================================
2 DYNAMIC LINK LIBRARY : CppShellExtInfotipHandler Project Overview
3 =============================================================================
5 /////////////////////////////////////////////////////////////////////////////
8 The code sample demonstrates creating a Shell infotip handler with C++. An
9 infotip handler is a shell extension handler that provides pop-up text when
10 the user hovers the mouse pointer over the object. It is the most flexible
11 way to customize infotips. The alternative way is to specify either a fixed
12 string or a list of certain file properties to be displayed (See the Infotip
13 Customization section in http://msdn.microsoft.com/en-us/library/cc144067.aspx)
15 The example infotip handler has the class ID (CLSID):
16 {A67511FE-371A-498D-9372-A27FDA58BE60}
18 It customizes the infotips of .cpp file objects. When you hover your mouse
19 pointer over a .cpp file object in the Windows Explorer, you will see an
20 infotip with the text:
22 File: <File path, e.g. D:\Test.cpp>
23 Lines: <Line number, e.g. 123 or N/A>
24 - Infotip displayed by CppShellExtInfotipHandler
27 /////////////////////////////////////////////////////////////////////////////
32 If you are going to use the Shell extension in a x64 Windows system, please
33 configure the Visual C++ project to target 64-bit platforms using project
34 configurations (http://msdn.microsoft.com/en-us/library/9yb4317s.aspx). Only
35 64-bit extension DLLs can be loaded in the 64-bit Windows Shell.
37 If the extension is to be loaded in a 32-bit Windows system, you can use the
38 default Win32 project configuration to build the project.
40 In a command prompt running as administrator, navigate to the folder that
41 contains the build result CppShellExtInfotipHandler.dll and enter the command:
43 Regsvr32.exe CppShellExtInfotipHandler.dll
45 The infotip handler is registered successfully if you see a message box
48 "DllRegisterServer in CppShellExtInfotipHandler.dll succeeded."
52 In a command prompt running as administrator, navigate to the folder that
53 contains the build result CppShellExtInfotipHandler.dll and enter the command:
55 Regsvr32.exe /u CppShellExtInfotipHandler.dll
57 The infotip handler is unregistered successfully if you see a message box
60 "DllUnregisterServer in CppShellExtInfotipHandler.dll succeeded."
63 /////////////////////////////////////////////////////////////////////////////
66 The following steps walk through a demonstration of the infotip handler code
69 Step1. If you are going to use the Shell extension in a x64 Windows system,
70 please configure the Visual C++ project to target 64-bit platforms using
71 project configurations (http://msdn.microsoft.com/en-us/library/9yb4317s.aspx).
72 Only 64-bit extension DLLs can be loaded in the 64-bit Windows Shell.
74 If the extension is to be loaded in a 32-bit Windows system, you can use the
75 default Win32 project configuration.
77 Step2. After you successfully build the sample project in Visual Studio 2010,
78 you will get a DLL: CppShellExtInfotipHandler.dll. Start a command prompt as
79 administrator, navigate to the folder that contains the file and enter the
82 Regsvr32.exe CppShellExtInfotipHandler.dll
84 The infotip handler is registered successfully if you see a message box saying:
86 "DllRegisterServer in CppShellExtInfotipHandler.dll succeeded."
88 Step3. Find a .cpp file in the Windows Explorer (e.g. FileInfotipExt.cpp in
89 the sample folder), and hover the mouse pointer over it. you will see an
90 infotip with the text:
92 File: <File path, e.g. D:\CppShellExtInfotipHandler\FileInfotipExt.cpp>
93 Lines: <Line number, e.g. 123 or N/A>
94 - Infotip displayed by CppShellExtInfotipHandler
96 Step4. In the same command prompt, run the command
98 Regsvr32.exe /u CppShellExtInfotipHandler.dll
100 to unregister the Shell infotip handler.
103 /////////////////////////////////////////////////////////////////////////////
106 A. Creating and configuring the project
108 In Visual Studio 2010, create a Visual C++ / Win32 / Win32 Project named
109 "CppShellExtInfotipHandler". In the "Application Settings" page of Win32
110 Application Wizard, select the application type as "DLL" and check the "Empty
111 project" option. After you click the Finish button, an empty Win32 DLL
114 -----------------------------------------------------------------------------
116 B. Implementing a basic Component Object Model (COM) DLL
118 Shell extension handlers are all in-process COM objects implemented as DLLs.
119 Making a basic COM includes implementing DllGetClassObject, DllCanUnloadNow,
120 DllRegisterServer, and DllUnregisterServer in (and exporting them from) the
121 DLL, adding a COM class with the basic implementation of the IUnknown
122 interface, preparing the class factory for your COM class. The relevant files
123 in this code sample are:
125 dllmain.cpp - implements DllMain and the DllGetClassObject, DllCanUnloadNow,
126 DllRegisterServer, DllUnregisterServer functions that are necessary for a
129 GlobalExportFunctions.def - exports the DllGetClassObject, DllCanUnloadNow,
130 DllRegisterServer, DllUnregisterServer functions from the DLL through the
131 module-definition file. You need to pass the .def file to the linker by
132 configuring the Module Definition File property in the project's Property
133 Pages / Linker / Input property page.
135 Reg.h/cpp - defines the reusable helper functions to register or unregister
136 in-process COM components in the registry:
137 RegisterInprocServer, UnregisterInprocServer
139 FileInfotipExt.h/cpp - defines the COM class. You can find the basic
140 implementation of the IUnknown interface in the files.
142 ClassFactory.h/cpp - defines the class factory for the COM class.
144 -----------------------------------------------------------------------------
146 C. Implementing the infotip handler and registering it for a certain file
150 Implementing the infotip handler:
152 The FileInfotipExt.h/cpp files define an infotip handler. Infotip handlers
153 must implement the IQueryInfo interface to create text for the tooltip, and
154 implement the IPersistFile interface for initialization.
156 class FileInfotipExt : public IPersistFile, public IQueryInfo
160 IFACEMETHODIMP GetClassID(CLSID *pClassID);
161 IFACEMETHODIMP IsDirty(void);
162 IFACEMETHODIMP Load(LPCOLESTR pszFileName, DWORD dwMode);
163 IFACEMETHODIMP Save(LPCOLESTR pszFileName, BOOL fRemember);
164 IFACEMETHODIMP SaveCompleted(LPCOLESTR pszFileName);
165 IFACEMETHODIMP GetCurFile(LPOLESTR *ppszFileName);
168 IFACEMETHODIMP GetInfoTip(DWORD dwFlags, LPWSTR *ppwszTip);
169 IFACEMETHODIMP GetInfoFlags(DWORD *pdwFlags);
172 1. Implementing IPersistFile
174 The Shell queries the extension for IPersistFile and calls its Load method
175 passing the file name of the item over which mouse is placed.
176 IPersistFile::Load opens the specified file and initializes the wanted data.
177 In this code sample, we save the absolute path of the file.
179 IFACEMETHODIMP FileInfotipExt::Load(LPCOLESTR pszFileName, DWORD dwMode)
181 // pszFileName contains the absolute path of the file to be opened.
182 return StringCchCopy(
184 ARRAYSIZE(m_szSelectedFile),
188 2. Implementing IQueryInfo
190 After IPersistFile is queried, the Shell queries the IQueryInfo interface
191 and the GetInfoTip method is called. GetInfoTip has an out parameter
192 ppwszTip of the type LPWSTR * which recieves the address of the tool tip
193 buffer. Please note that the memory pointed by *ppwszTip must be allocated
194 by calling CoTaskMemAlloc. Shell knows to call CoTaskMemFree to free the
195 memory when the info tip is no longer needed.
197 In this code sample, the example infotip is composed of the file path and
198 the count of text lines.
200 const int cch = MAX_PATH + 512;
201 *ppwszTip = static_cast<LPWSTR>(CoTaskMemAlloc(cch * sizeof(wchar_t)));
202 if (*ppwszTip == NULL)
204 return E_OUTOFMEMORY;
207 // Prepare the text of the infotip. The example infotip is composed of
208 // the file path and the count of code lines.
209 wchar_t szLineNum[50];
212 HRESULT hr = StringCchPrintf(*ppwszTip, cch,
213 L"File: %s\nLines: %s\n- Infotip displayed by CppShellExtInfotipHandler",
214 m_szSelectedFile, szLineNum);
217 CoTaskMemFree(*ppwszTip);
220 The IQueryInfo::GetInfoFlags method is not currently used. We simply return
221 E_NOTIMPL from the method.
224 Registering the handler for a certain file class:
226 The CLSID of the handler is declared at the beginning of dllmain.cpp.
228 // {A67511FE-371A-498D-9372-A27FDA58BE60}
229 const CLSID CLSID_FileInfotipExt =
230 { 0xA67511FE, 0x371A, 0x498D, { 0x93, 0x72, 0xA2, 0x7F, 0xDA, 0x58, 0xBE, 0x60 } };
232 When you write your own handler, you must create a new CLSID by using the
233 "Create GUID" tool in the Tools menu, and specify the CLSID value here.
235 Infotip handlers can be associated with a file class. The handlers are
236 registered under the following subkey.
238 HKEY_CLASSES_ROOT\<File Type>\shellex\{00021500-0000-0000-C000-000000000046}
240 The registration of the infotip handler is implemented in the
241 DllRegisterServer function of dllmain.cpp. DllRegisterServer first calls the
242 RegisterInprocServer function in Reg.h/cpp to register the COM component.
243 Next, it calls RegisterShellExtInfotipHandler to associate the handler with a
244 certain file type. If the file type starts with '.', it tries to read the
245 default value of the HKCR\<File Type> key which may contain the Program ID to
246 which the file type is linked. If the default value is not empty, use the
247 Program ID as the file type to proceed the registration.
249 For example, this code sample associates the handler with '.cpp' files.
250 HKCR\.cpp has the default value 'VisualStudio.cpp.10.0' by default when
251 Visual Studio 2010 is installed, so we proceed to register the handler under
252 HKCR\VisualStudio.cpp.10.0\ instead of under HKCR\.cpp. The following keys
253 and values are added in the registration process of the sample handler.
259 ForceRemove {A67511FE-371A-498D-9372-A27FDA58BE60} =
260 s 'CppShellExtInfotipHandler.FileInfotipExt Class'
262 InprocServer32 = s '<Path of CppShellExtInfotipHandler.DLL file>'
264 val ThreadingModel = s 'Apartment'
268 NoRemove .cpp = s 'VisualStudio.cpp.10.0'
269 NoRemove VisualStudio.cpp.10.0
273 {00021500-0000-0000-C000-000000000046} =
274 s '{A67511FE-371A-498D-9372-A27FDA58BE60}'
279 The unregistration is implemented in the DllUnregisterServer function of
280 dllmain.cpp. It removes the HKCR\CLSID\{<CLSID>} key and the
281 HKCR\<File Type>\shellex\{00021500-0000-0000-C000-000000000046} key.
284 /////////////////////////////////////////////////////////////////////////////
287 MSDN: Initializing Shell Extensions
288 http://msdn.microsoft.com/en-us/library/cc144105.aspx
290 MSDN: IQueryInfo Interface
291 http://msdn.microsoft.com/en-us/library/bb761359.aspx
293 The Complete Idiot's Guide to Writing Shell Extensions - Part III
294 http://www.codeproject.com/KB/shell/ShellExtGuide3.aspx
297 /////////////////////////////////////////////////////////////////////////////